﻿/******************************************************************************
 *  LOG_ENABLED
 * 
 *  Enables / disables logging features throughout the appplication.
 *****************************************************************************/
#define LOG_ENABLED



/******************************************************************************
 * 
 * Namespaces..
 * 
 *****************************************************************************/
using System;
using System.Diagnostics;



namespace AFCEPF.BankApplication.DAL
{
    public class Logger
    {
        private Type            _type;
        private LoggerOptions   _options;
        private string          _headerformatString;


        /// <summary>
        /// private contructor.
        /// </summary>
        /// <param name="type">The type.</param>
        private Logger(Type type)
        {
            _type   = type;
            _options = LoggerOptions.Standard;
            Log("-> Initializing Log For : [{0}]", _type.Name);

        }




        /// <summary>
        /// Gets the logger.
        /// </summary>
        /// <param name="target">The target.</param>
        /// <param name="options">The options.</param>
        /// <returns>the logger.</returns>
        public static Logger GetLogger(object target, LoggerOptions options = LoggerOptions.Standard)
        {
            return new Logger(target.GetType()){ Options = options};
        }

        /// <summary>
        /// Gets the logger.
        /// </summary>
        /// <param name="targetType">Type of the target.</param>
        /// <param name="options">The options.</param>
        /// <returns>the logger.</returns>
        public static Logger GetLogger(Type targetType, LoggerOptions options = LoggerOptions.Standard)
        {
            return new Logger(targetType) { Options = options };
        }



        /// <summary>
        /// Logs the specified text.
        /// </summary>
        /// <param name="text">The text.</param>
        [Conditional("LOG_ENABLED")]
        public void Log(string text)
        {
            Log("{0}",text);
        }

        /// <summary>
        /// Logs the specified text at the specified format.
        /// </summary>
        /// <param name="format">The format.</param>
        /// <param name="args">The args.</param>
        [Conditional("LOG_ENABLED")]
        public void Log(string format, params string[] args)
        {
            const string CRLF = "\r\n";
            var logged = string.Format(format, args);
            var result = string.Format("{2}[{0}]:{2}\t{1}{2}", getHeader(), logged, CRLF);

            Console.WriteLine(result);
            
        }


        /// <summary>
        /// Gets the header to be inserted at the beginning of each
        /// log line (like : functionName or.. DateTime.FunctionName.. etc.).
        /// </summary>
        /// <returns>The line-level log header string.</returns>
        internal string getHeader()
        {
            var stack = new StackTrace();

            switch (Options)
            {
                case LoggerOptions.Minimal:
                    _headerformatString = string.Format("{0}",DateTime.Now.ToLongTimeString() + DateTime.Now.Millisecond);
                    break;
                case LoggerOptions.Standard:
                    _headerformatString = string.Format("{0} : {1}.{2}.{3}",  DateTime.Now.ToLongTimeString() + DateTime.Now.Millisecond,
                                                                            _type.Namespace, 
                                                                            _type.Name, 
                                                                            stack.GetFrame(4).GetMethod().Name);
                    break;
                case LoggerOptions.Verbose:
                    _headerformatString = string.Format("{0}", stack.ToString());
                    break;
                default:
                    break;

            }
            return _headerformatString;
        }



        /// <summary>
        /// Gets or sets the options.
        /// </summary>
        public LoggerOptions Options
        {
            get { return _options; }
            set { _options = value; }
        }

        /// <summary>
        /// Logger Ooptions.
        /// </summary>
        public enum LoggerOptions
        {
            Minimal,
            Standard,
            Verbose,
        }

    }
}
